package com.newtouch.bxzs.business.train.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newtouch.bxzs.business.enclosure.mapper.AttachmentMapper;
import com.newtouch.bxzs.business.enclosure.service.AttachmentService;
import com.newtouch.bxzs.business.product.mapper.UserMapper;
import com.newtouch.bxzs.business.train.controller.KnowledgeCardController;
import com.newtouch.bxzs.business.train.mapper.KnowledgeBaseMapper;
import com.newtouch.bxzs.business.train.model.bo.KnowledgeBaseBO;
import com.newtouch.bxzs.business.train.model.vo.KnowledgeBaseVO;
import com.newtouch.bxzs.business.train.model.vo.NewKnowledgeBaseVO;
import com.newtouch.bxzs.business.train.service.KnowledgeBaseService;
import com.newtouch.bxzs.common.base.BaseErrorEnum;
import com.newtouch.bxzs.common.base.BaseException;
import com.newtouch.bxzs.common.base.em.ButtonTypeEnum;
import com.newtouch.bxzs.common.base.em.PublishStatusEnum;
import com.newtouch.bxzs.common.base.model.Attachment;
import com.newtouch.bxzs.common.base.model.KnowledgeBase;
import com.newtouch.bxzs.common.base.model.User;
import com.newtouch.bxzs.common.base.model.vo.EnclosureVO;
import com.newtouch.bxzs.common.base.util.CheckPublishDateUtils;
import com.newtouch.bxzs.common.base.util.UserDetailUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * 知识库业务逻辑
 *
 * <p>
 * <b>History:</b>
 * <table border="1">
 * <tr>
 * <th>Date</th>
 * <th>Operator</th>
 * <th>Memo</th>
 * </tr>
 * <tr>
 * <td>2021/1/11 9:36</td>
 * <td>lingshouyi</td>
 * <td>Create</td>
 * </tr>
 * </table>
 *
 * @author lingshouyi
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
public class KnowledgeBaseServiceImpl implements KnowledgeBaseService {

    @Autowired
    private KnowledgeBaseMapper knowledgeBaseMapper;

    @Autowired
    private AttachmentService attachmentService;

    @Autowired
    private AttachmentMapper attachmentMapper;


    @Resource
    private UserMapper userMapper;

    /**
     * 获取配置的知识库的发布时间的最大限制
     */
    @Value("${publishTimeConfig.maxPublishTime}")
    private Integer maxPublishTime;

    /**
     * 获取配置的广告的撤销时间的最大限制
     */
    @Value("${revokeTimeConfig.maxRevokeTime}")
    private String maxRevokeTime;

    /**
     * 已发布状态码常量
     */
    private static final String PUBLISHED_STATUS = PublishStatusEnum.PUBLISHED_STATUS.getResultCode();
    /**
     * 未发布状态码常量
     */
    private static final String UNPUBLISHED_STATUS = PublishStatusEnum.UNPUBLISH_STATUS.getResultCode();
    /**
     * 已取消状态码常量
     */
    private static final String REVOKED_STATUS = PublishStatusEnum.REVOKED_STATUS.getResultCode();

    /**
     * 静态变量：系统日志
     */
    private static final Log logger = LogFactory.getLog(KnowledgeCardController.class);

    @Override
    public IPage<KnowledgeBaseBO> getKnowledgeBaseList(KnowledgeBaseVO knowledgeBaseVO, Boolean flag) {
        if (BeanUtil.isEmpty(knowledgeBaseVO)) {
            return null;
        }
        /*当前登录用户id*/
        String createUserId = null;
        QueryWrapper<KnowledgeBase> qw = new QueryWrapper<>();
        if (flag) {
            knowledgeBaseVO.setPublishStatus(PUBLISHED_STATUS);
            qw.eq("PUBLISH_STATUS", PUBLISHED_STATUS);
        } else {
            createUserId = Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId();
        }
        /* 分页参数 */
        Page<KnowledgeBaseBO> page = new Page<>(knowledgeBaseVO.getCurrentPage(), knowledgeBaseVO.getPageSize());
        /* 知识卡片列表信息 */
        IPage<KnowledgeBaseBO> knowledgeCardList = knowledgeBaseMapper.getKnowledgeBaseList(
                createUserId,
                knowledgeBaseVO.getKnowledgeBaseTitle(),
                knowledgeBaseVO.getKnowledgeBaseType(),
                knowledgeBaseVO.getPublishStatus(), page);
        /* 判断是否为空 */
        if (CollectionUtils.isEmpty(knowledgeCardList.getRecords())) {
            return null;
        }
        return knowledgeCardList;
    }

    @Override
    public KnowledgeBaseBO getKnowledgeBaseDetail(String knowledgeBaseId) {
        /* 判断是否为空 */
        if (StringUtils.isEmpty(knowledgeBaseId)) {
            throw new BaseException(BaseErrorEnum.BODY_NOT_MATCH);
        }
        /* 创建一个详情BO */
        KnowledgeBaseBO knowledgeBaseBO = new KnowledgeBaseBO();
        /* 将源数据copy到BO */
        BeanUtil.copyProperties(knowledgeBaseMapper.selectById(knowledgeBaseId), knowledgeBaseBO);
        /* 构造条件 */
        User user = userMapper.selectById(knowledgeBaseBO.getUpdateUserId());
        if (!BeanUtil.isEmpty(user)) {
            knowledgeBaseBO.setPublishUserName(user.getUserName());
        }
        HashMap<String, List<String>> result = attachmentService
                .getEnclosureList(new EnclosureVO(knowledgeBaseId, null));
        if (result != null) {
            knowledgeBaseBO.setAttachments(result);
        }
        return knowledgeBaseBO;
    }

    @Override
    public String modifyKnowledgeBase(NewKnowledgeBaseVO newKnowledgeBaseVO) {
        if (BeanUtil.isEmpty(newKnowledgeBaseVO)) {
            return null;
        }
        KnowledgeBase knowledgeBase = new KnowledgeBase();
        /* 将源数据copy到knowledgeDB中 */
        BeanUtil.copyProperties(newKnowledgeBaseVO, knowledgeBase);
        /* 校验必填项 */
        if (StringUtils.isEmpty(knowledgeBase.getKnowledgeBaseTitle())
                || StringUtils.isEmpty(knowledgeBase.getKnowledgeBaseType())
                || StringUtils.isEmpty(knowledgeBase.getKnowledgeBaseContent())) {
            throw new BaseException(BaseErrorEnum.REQUIRED_ITEM_NULL);
        }
        /* 效验发布时间和撤销时间是否正确 */
        if (knowledgeBase.getRevokeTime() != null || knowledgeBase.getPublishTime() != null) {
            /* 检验发布撤销时间 */
            CheckPublishDateUtils.checkDate(knowledgeBase.getPublishTime(), knowledgeBase.getRevokeTime(),
                    maxPublishTime, maxRevokeTime);
        }
        /* 当传入知识库id为空时,新增 */
        if (StringUtils.isEmpty(knowledgeBase.getKnowledgeBaseId())) {
            knowledgeBase.setCreateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
            knowledgeBase.setCreateTime(new Date());
            knowledgeBase.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
            knowledgeBase.setUpdateTime(new Date());
            /* 传入的按钮类型 */
            sendOrTemporary(newKnowledgeBaseVO.getButtonType(), knowledgeBase);
            knowledgeBaseMapper.insert(knowledgeBase);
            logger.info("新增成功");
        } else {
            /* 修改状态 */
            knowledgeBase.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
            knowledgeBase.setUpdateTime(new Date());
            /* 传入的按钮类型 */
            sendOrTemporary(newKnowledgeBaseVO.getButtonType(), knowledgeBase);
            QueryWrapper<KnowledgeBase> qw = new QueryWrapper<>();
            qw.eq("KNOWLEDGE_BASE_ID", newKnowledgeBaseVO.getKnowledgeBaseId());
            knowledgeBaseMapper.update(knowledgeBase, qw);
            logger.info("修改成功");
        }
        /* 返回当前知识库ID */
        return knowledgeBase.getKnowledgeBaseId();
    }

    @Override
    public Integer changeKnowledgeBaseState(String knowledgeBaseId, String publishStatus) {
        if (StringUtils.isEmpty(knowledgeBaseId)) {
            throw new BaseException(BaseErrorEnum.BODY_NOT_MATCH);
        }
        QueryWrapper<KnowledgeBase> qw = new QueryWrapper<>();
        qw.eq("KNOWLEDGE_BASE_ID", knowledgeBaseId);
        KnowledgeBase knowledgeBase = knowledgeBaseMapper.selectOne(qw);
        /* 如果为撤销，则设置撤销时间 */
        if (REVOKED_STATUS.equals(publishStatus)) {
            knowledgeBase.setRevokeTime(new Date());
        }
        /* 如果为发布，则设置发布时间 */
        if (PUBLISHED_STATUS.equals(publishStatus)) {
            knowledgeBase.setPublishTime(new Date());
        }
        /* 设置发布状态，修改人，和修改时间 */
        knowledgeBase.setPublishStatus(publishStatus);
        knowledgeBase.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
        knowledgeBase.setUpdateTime(new Date());

        return knowledgeBaseMapper.update(knowledgeBase, qw);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer deleteKnowledgeBase(List<String> knowledgeBaseIds) {
        /* 判断知识库ID集合是否为空 */
        if (CollectionUtils.isEmpty(knowledgeBaseIds)) {
            throw new BaseException(BaseErrorEnum.BODY_NOT_MATCH);
        }
        /* 判断ID集合是否存在空字符串,如果有就移除. */
        for (String knowledgeBaseId : knowledgeBaseIds) {
            if (StringUtils.isEmpty(knowledgeBaseId)) {
                knowledgeBaseIds.remove(knowledgeBaseId);
            }
        }
        /* 判断勾选中的知识库是否存在已发布的 */
        QueryWrapper<KnowledgeBase> qw = new QueryWrapper<>();
        qw.in("KNOWLEDGE_BASE_ID", knowledgeBaseIds).eq("PUBLISH_STATUS", PUBLISHED_STATUS);
        List<KnowledgeBase> knowledgeBaseList = knowledgeBaseMapper.selectList(qw);
        if (CollectionUtils.isEmpty(knowledgeBaseList)) {
            /*知识库删除成功后,删除附件*/
            if (knowledgeBaseMapper.deleteBatchIds(knowledgeBaseIds) > 0) {
                return attachmentMapper.delete(new QueryWrapper<Attachment>().in("ATTACHMENT_RELATION_ID", knowledgeBaseIds));
            }
            logger.info("删除成功");
        } else {
            throw new BaseException(BaseErrorEnum.PUBLISH_STATUS);
        }
        return null;
    }

    /**
     * 发布/暂存
     *
     * @param buttonType    按钮类型
     * @param knowledgeBase 知识库实体
     */
    private void sendOrTemporary(String buttonType, KnowledgeBase knowledgeBase) {
        /* 点击发布按钮 */
        if (buttonType.equals(ButtonTypeEnum.PUBLIC_BUTTON.getCode())) {
            /* 设置为已发布状态 */
            knowledgeBase.setPublishStatus(PUBLISHED_STATUS);
            knowledgeBase.setPublishTime(new Date());
        }
        /* 点击暂存按钮 */
        if (buttonType.equals(ButtonTypeEnum.TEMPORARY_BUTTON.getCode())) {
            /* 设置状态为未发布状态 */
            knowledgeBase.setPublishStatus(UNPUBLISHED_STATUS);
        }
    }

}
